/**
 * @file AudioMqtt.cpp
 * @brief 该文件包含ESP32项目的MQTT音频处理函数的实现。
 *  */

#include "AudioMqtt/AudioMqtt.h"
#include "config.h"
#include "audiopage/audiopage.h"
#include "generated/gui_guider.h" //LVGL库
#include "custom/custom.h"
#include "generated/events_init.h"
#include "lvgl.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/stream_buffer.h"

bool audio_recive = false;      //接收音频标志位
extern PubSubClient mqttClient;
extern float volume;
extern bool list_refresh_falg;
extern StreamBufferHandle_t audioStreamBuffer;
extern TaskHandle_t mqttProcessingTaskHandle;

void audioCallback(char* topic, byte* payload, unsigned int length);
void sendData(const uint8_t *data, uint16_t len);
void sendStopSignal();

#include "AudioMqtt/AudioMqtt.h"
#include "config.h"
#include "audiopage/audiopage.h"
#include "generated/gui_guider.h" //LVGL库
#include "custom/custom.h"
#include "generated/events_init.h"
#include "lvgl.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/stream_buffer.h"


extern PubSubClient mqttClient;
extern float volume;
extern bool list_refresh_falg;
extern StreamBufferHandle_t audioStreamBuffer;
extern TaskHandle_t mqttProcessingTaskHandle;

/**
 * @brief 处理音频数据的MQTT消息回调函数。
 * 
 * 该函数处理接收到的音频数据，进行转换并发送到流缓冲区。
 * 如果接收到静音信号（0xFF），则将静音信号发送到流缓冲区。
 * 
 * @param topic 接收到的MQTT消息的主题。
 * @param payload 接收到的MQTT消息的负载。
 * @param length 负载的长度。
 */
void audioCallback(char* topic, byte* payload, unsigned int length) {

    for (int i = 0; i < length; i++) {
    recive_16bit_list[i] = ((payload[i] - 128) << 5) * 5;
  }
    if (length == 1 && payload[0] == 0xFF) {
    // 将静音信号发送到流缓冲区
    xStreamBufferSend(audioStreamBuffer, payload, length, 0);
    Serial.printf("静音0");//接收音频数据完成
    audio_recive = false;
    return;
  }
  audio_recive = true;//接收到音频数据
  xStreamBufferSend(audioStreamBuffer, payload, length, 0);
}

/**
 * @brief 通过MQTT发送音频数据。
 * 
 * 该函数检查MQTT客户端是否已连接，并将提供的数据发送到指定的主题。
 * 如果客户端未连接或发布失败，则打印错误消息。
 * 
 * @param data 指向要发送的数据的指针。
 * @param len 要发送的数据的长度。
 */
void sendData(const uint8_t  *data, uint16_t len)
{
  if(MQTT_CONNECTED==mqttClient.state())
  {
    if(false  == mqttClient.publish(PUBTOPIC, data,len,0))
    {
      Serial.println("sendfailed");
    }

  }
  else
  {
    Serial.println("not connect");
  }
    
}

/**
 * @brief 通过MQTT发送停止信号。
 * 
 * 该函数通过MQTT将预定义的停止信号（0xFF）发送到指定的主题。
 * 如果客户端未连接或发布失败，则打印错误消息。
 */
void sendStopSignal()
{
  const uint8_t stopMessage[] = {0xFF}; // 示例停止信号
  if (MQTT_CONNECTED == mqttClient.state())
  {
    if (false == mqttClient.publish(PUBTOPIC, stopMessage, sizeof(stopMessage), 0))
    {
      Serial.println("停止信号发送失败");
    }
  }
  else
  {
    Serial.println("未连接");
  }
}